/*
 * @ProjectName: 编程学习
 * @Copyright:   2019 HangZhou Yi Dev, Ltd. All Right Reserved.
 * @address:     http://Yi.tech
 * @date:        2019/5/20 20:57
 * @email:       https:yiyuery.github.io/NoteBooks
 * @description: 本内容仅限于编程技术学习使用，转发请注明出处.
 */
package com.example.swagger.common.configuration;

import org.yaml.snakeyaml.Yaml;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 *
 * </p>
 *
 * @author Yi
 * @version v1.0.0
 * @date 2019-06-05 21:55
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人} 2019-06-05
 * @modify reason: {方法名}:{原因}
 * ...
 */
public class ApplicationYamlLoader {

    private static Map<String, Object> APPLICATION_YAML_PROPERTIES = new HashMap<String, Object>();

    public static <T> T getPropsByKey(String key, Class<T> clazz, T defaultValue) {
        return Objects.nonNull(APPLICATION_YAML_PROPERTIES.get(key)) ? clazz.cast(APPLICATION_YAML_PROPERTIES.get(key)) : defaultValue;
    }

    public static <T> T getPropsByKey(String key, Class<T> clazz) {
        return getPropsByKey(key, clazz, null);
    }

    public static void loadDefaultProps() {
        Yaml yaml = new Yaml();
        InputStream inputStream = ApplicationYamlLoader.class.getResourceAsStream("/application.yaml");
        for (Object o : yaml.loadAll(inputStream)) {
            Map map = (Map) o;
            iteratorYml(map, null);
        }
    }

    /**
     * 外部自定义加载配置
     *
     * @param yamlPath
     */
    public static void reload(String yamlPath) {
        File y = new File(yamlPath);
        if (!y.exists() || y.isDirectory() || !yamlPath.endsWith("yaml")) {
            throw new IllegalArgumentException("can't reload props by not exist file!");
        }
        try {
            Yaml yaml = new Yaml();
            InputStream inputStream = new BufferedInputStream(new FileInputStream(Paths.get(yamlPath).toFile()));
            for (Object o : yaml.loadAll(inputStream)) {
                Map map = (Map) o;
                iteratorYml(map, null);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * 迭代解析
     *
     * @param map
     * @param key
     */
    private static void iteratorYml(Map map, String key) {
        for (Object o : map.entrySet()) {
            Map.Entry entry = (Map.Entry) o;
            Object key2 = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof LinkedHashMap) {
                if (key == null) {
                    iteratorYml((Map) value, key2.toString());
                } else {
                    iteratorYml((Map) value, key + "." + key2.toString());
                }
            }
            if (Objects.isNull(key)) {
                APPLICATION_YAML_PROPERTIES.put(key2.toString(), value);
            } else {
                APPLICATION_YAML_PROPERTIES.put(key + "." + key2.toString(), value);
            }
        }
    }
}
